package org.catj.app;

import org.catj.entity.Attribute;
import org.catj.entity.AttributeScale;
import org.catj.entity.Dwarf;
import org.catj.util.JobInfo;
import org.catj.xml.CreatureDefinition;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.*;

public class DwarfRecruiter {
    private List<Dwarf> dwarves = new ArrayList<Dwarf>();

    public List<Dwarf> getDwarves() {
        return dwarves;
    }

    public void setDwarves(List<Dwarf> dwarves) {
        this.dwarves = dwarves;
    }
    public String getBestDwarfForJob(String jobName){
        String bestDwarves = "";
        float bestScore = 0;
        for(Dwarf dwarf : getDwarves()){
            float score = dwarf.getJobScore(jobName);
            if(score > bestScore){
                bestDwarves = dwarf.getName();
                bestScore = score;
            }
            else if(score == bestScore){
                bestDwarves += "and" + dwarf.getName();
            }
        }
        return  bestDwarves;
    }
    public Map<Float, Dwarf> getSortedDwarvesForJob(String jobName){
        Map<Float, Dwarf> orderedMap = new TreeMap<Float, Dwarf>();
        for(Dwarf dwarf : getDwarves()){
            orderedMap.put(dwarf.getJobScore(jobName), dwarf);
        }
        return orderedMap;
    }

    public void parseDwarf(Element element) {
        Dwarf dwarf = new Dwarf();
        dwarf.setName(getTagValue(CreatureDefinition.NAME, element));
        parseAttributes(element, dwarf);
        parseTraits(element, dwarf);
        dwarves.add(dwarf);
        calculateJobScores();
    }

    private void parseTraits(Element element, Dwarf dwarf) {
        NodeList traits = element.getElementsByTagName(CreatureDefinition.TRAIT_ROOT);
        for (int i = 0; i < traits.getLength(); i++) {
            Node node = traits.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element traitElement = (Element) node;
                NodeList traitList = traitElement.getElementsByTagName(CreatureDefinition.TRAIT);
                for (int j = 0; j < traitList.getLength(); j++) {
                    dwarf.addTrait(traitList.item(j).getAttributes().getNamedItem("name").getNodeValue());
                }
            }
        }
    }

    private void parseAttributes(Element element, Dwarf dwarf) {
        NodeList attrs = element.getElementsByTagName(CreatureDefinition.ATTRIBUTES_ROOT);
        for (int i = 0; i < attrs.getLength(); i++) {
            Node node = attrs.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element attrElement = (Element) node;
                for (String attr : CreatureDefinition.ATTRIBUTES) {
                    AttributeScale scale = JobInfo.getAttributeScales().get(attr);
                    dwarf.addAttribute(attr, Integer.parseInt(getTagValue(attr, attrElement)), scale);
                }
            }
        }
    }

    private void calculateJobScores() {
        for (Dwarf dwarf : dwarves) {
            for (String jobName : JobInfo.getJobAttributes().keySet()) {
                List<String> attributes = JobInfo.getJobAttributes().get(jobName);
                float sum = 0;
                int count = 0;
                for (String attribute : attributes) {
                    Attribute jobAttr = dwarf.getAttribute(attribute);
                    sum += jobAttr.getRank();
                    count++;
                }
                dwarf.addJobScore(jobName, (sum / count));
            }
        }
    }

    private static String getTagValue(String tag, Element element) {
        NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
        return nodeList.item(0).getNodeValue();
    }

}
